# -*- encoding: utf-8 -*-
"""
App级的共通类
"""
import traceback
import json

from tornado.util import unicode_type
from tornado.escape import utf8
from tornado.web import RequestHandler

from common import  config


class BaseRequestHandler(RequestHandler):
    """ Inherited from tornado.web.RequestHandler
    """
    def __init__(self, application, request, **kwargs):
        super(BaseRequestHandler, self).__init__(application, request,
                                                 **kwargs)

    def get_current_user(self):
        user_name = self.get_secure_cookie('user_name', None)
        access_token = self.get_secure_cookie('access_token', None)
        if user_name and access_token:
            user = dict(user_name=user_name, access_token=access_token)
        else:
            user = None
        return user

    def write_api(self, dict_content, code='0', json_ascii=True,
                  json_indent=None):
        chunk = {'code': code}
        if isinstance(dict_content, dict):
            chunk.update(dict_content)
        else:
            type_content = type(dict_content)
            raise TypeError, 'Api content should be dictionary, Not be %s' % \
                type_content

        if self._finished:
            raise RuntimeError("Cannot write() after finish()")
        if not isinstance(chunk, (bytes, unicode_type, dict)):
            message = "write() only accepts bytes, unicode, and dict objects"
            if isinstance(chunk, list):
                message += (". Lists not accepted for security reasons; see "
                            "http://www.tornadoweb.org/en/stable/web.html#tor"
                            "nado.web.RequestHandler.write")
            raise TypeError(message)
        if isinstance(chunk, dict):
            chunk = json.dumps(
                chunk, ensure_ascii=json_ascii, indent=json_indent
                ).replace("</", "<\\/")
            self.set_header("Content-Type", "application/json; charset=UTF-8")
        chunk = utf8(chunk)
        self._write_buffer.append(chunk)


class APIRequestHandler(BaseRequestHandler):
    """Used by API providing Handlers
    """
    def write_error(self, status_code, **kwargs):
        if self.settings.get("serve_traceback") and "exc_info" in kwargs:
            # in debug mode, try to send a traceback
            # self.set_header('Content-Type', 'text/plain')
            # for line in traceback.format_exception(*kwargs["exc_info"]):
            #     self.write(line)
            # self.finish()
            if status_code in (405, ):
                error = {'code': '1041', 'msg': config.CODE1041}
            elif status_code in (400, ):
                error = {'code': '1002', 'msg': config.CODE1002}
            else:
                error = {'code': '1003', 'msg': config.CODE1003}
            response_body = json.dumps(error, ensure_ascii=False)
            response_content_type = 'application/json; charset=UTF-8'
            self.set_header('Content-Type', response_content_type)
            self.set_status(200, 'OK')
            self.write(response_body)
        else:
            if status_code in (405, ):
                error = {'code': '1041', 'msg': config.CODE1041}
            elif status_code in (400, ):
                error = {'code': '1002', 'msg': config.CODE1002}
            else:
                error = {'code': '1003', 'msg': config.CODE1003}
            response_body = json.dumps(error, ensure_ascii=False)
            response_content_type = 'application/json; charset=UTF-8'
            self.set_header('Content-Type', response_content_type)
            self.set_status(200, 'OK')
            self.write(response_body)
            self.finish()

    def prepare(self):
        print self.request.arguments
        self.set_header('Access-Control-Allow-Origin', '*')
        self.set_header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS')
        self.set_header('Access-Control-Allow-Headers', '*')


class WebRequestHandler(BaseRequestHandler):
    """Used by WEB renderng Handlers
    """
    def write_error(self, status_code, **kwargs):
        if self.settings.get("serve_traceback") and "exc_info" in kwargs:
            # in debug mode, try to send a traceback
            self.set_header('Content-Type', 'text/plain')
            for line in traceback.format_exception(*kwargs["exc_info"]):
                self.write(line)
            self.finish()
        else:
            self.finish("<html><title>%(code)d: %(message)s</title>"
                        "<body>%(code)d: %(message)s</body></html>" % {
                            "code": status_code,
                            "message": self._reason,
                        })
